/*
 * Propiedad.java
 *
 * Copyright 2011 Universidad Francisco de Paula Santander (UFPS).
 * Todos los Derechos Reservados.
 * Creado el 21/06/2009, 11:05:38 PM
 */

package com.ufps.cuatro.modelo.representacion;

import java.util.ArrayList;

import com.ufps.cuatro.util.base.ObjectBase;

/**
 * <i><b>Propiedad:</b></i> <p>Esta Clase Representa una Propiedad de un Control
 * Swing.</p>
 * 
 * @author Carlos A. Torres C. - Dolly E. Guerrero. <https://code.google.com/p/tesis4dor/>
 * @version 1.0 21/06/2009
 * @see ObjectBase
 */
public class Propiedad extends ObjectBase{
    private static final long serialVersionUID = 1545631343336307451L;
    
    /**
     * Indica el modo de devolución de la Propiedad.
     */
    public final static int MODO_GET = 0;
    /**
     * Indica el modo de asignación de la Propiedad.
     */
    public final static int MODO_SET = 1;
    
    private String strName;
    private String strAlias;
    private String strTooltips;
    private String strSet;
    private String strGet;
    private String strRequeridas;
    private boolean boolEditable;
    private boolean boolVacio;
    
    private ArrayList<ParametroPropiedad> objParametrosSet;
    private ArrayList<ParametroPropiedad> objParametrosGet;
    
    private boolean aplicada = false;
    private int inicializado = 0;
    private int contexto = 0;
    
    private boolean viewSet = false;
    private boolean viewGet = false;
    
    /**
     * Indica que la Propiedad no ha sido inicializada.
     */
    public static int INIT_NULL = 0;
    /**
     * Indica que la Propiedad ha sido inicializada por el usuario.
     */
    public static int INIT_USUARIO = 1;
    /**
     * Indica que la Propiedad ha sido inicializada por defecto por la Aplicación.
     */
    public static int INIT_APP = 2;
    /**
     * Indica que la Propiedad ha sido inicializada desde un archivo de Propiedades.
     */
    public static int INIT_PROPERTIES = 3;
    /**
     * Representa la Propiedad Texto.
     */
    public static String NAME_PROPERTIES_TEXT = "Text";
    /**
     * Representa la Propiedad ToolTips.
     */
    public static String NAME_PROPERTIES_TOOLTIPS = "ToolTips";
    /**
     * Representa la Propiedad Icono.
     */
    public static String NAME_PROPERTIES_ICON = "Icon";
    /**
     * Representa la Propiedad Color Texto.
     */
    public static String NAME_PROPERTIES_FOREGROUND = "Foreground";
    /**
     * Representa la Propiedad Color Fondo.
     */
    public static String NAME_PROPERTIES_BACKGROUND = "Background";
    /**
     * Representa la Propiedad Estado.
     */
    public static String NAME_PROPERTIES_ENABLED = "Enabled";
    /**
     * Representa la Propiedad Color Opaco.
     */
    public static String NAME_PROPERTIES_OPAQUE = "Opaque";
    /**
     * Representa la Propiedad Texto Editable.
     */
    public static String NAME_PROPERTIES_EDITABLE = "Editable";
    /**
     * Representa la Propiedad Seleccionado.
     */
    public static String NAME_PROPERTIES_SELECTED = "Selected";
    
    public String strValueTempParametro = "";

    /**
     * Constructor por defecto
     */
    public Propiedad() {
        this.inicializado = INIT_NULL;
        this.objParametrosSet = new ArrayList<ParametroPropiedad>();
    }
    
    /**
     * Constructor que incializa Propiedades y Referencias.
     * @param id Propiedad utilizada para identificar el indice dentro de los archivos de
     * propiedades.
     * @param name Nombre de la Propiedad.
     * @param alias Alias de la Propiedad.
     * @param tooltips Mensaje de Ayuda Informativa.
     * @param set Definicón por Defecto para su Método de Modificación.
     * @param get Definicón por Defecto para su Método de Acceso.
     * @param requeridas Indices de Propiedades requeridas para la implementación.
     * @param contexto  
     */
    public Propiedad(int id, String name, String alias, String tooltips, String set, String get, String requeridas, int contexto, boolean boolEditable, boolean boolVacio) {
        this.id = id;
        this.strName = name;
        this.strAlias = alias;
        this.strTooltips = tooltips;
        this.strSet = set;
        this.strGet = get;
        this.strRequeridas = requeridas;
        this.contexto = contexto;        
        this.boolEditable = boolEditable;
        this.boolVacio = boolVacio;
        this.objParametrosSet = new ArrayList<ParametroPropiedad>();
    }
    
    /**
     * Devuelve el boolean que determina si la propiedad es editable.
     * @return boolean que determina si la propiedad es editable.
     */
    public boolean isEditable() {
        return boolEditable;
    }

    /**
     * Establece el boolean que determina si la propiedad es editable.
     * @param boolean que determina si la propiedad es editable.
     */
    public void setEditable(boolean boolEditable) {
        this.boolEditable = boolEditable;
    }
    
    /**
     * Devuelve el boolean que determina si la propiedad puede ser vacia.
     * @return boolean que determina si la propiedad puede ser vacia.
     */
    public boolean isEmpty() {
        return boolVacio;
    }

    /**
     * Establece el boolean que determina si la propiedad puede ser vacia.
     * @param boolean que determina si la propiedad puede ser vacia.
     */
    public void setEmpty(boolean boolVacio) {
        this.boolVacio = boolVacio;
    }

    /**
     * Devuelve el Alias de la Propiedad.
     * @return Alias de la Propiedad.
     */
    public String getAlias() {
        return strAlias;
    }

    /**
     * Establece el Alias de la Propiedad.
     * @param alias Alias de la Propiedad.
     */
    public void setAlias(String alias) {
        this.strAlias = alias;
    }   

    /**
     * Devuelve el Nombre de la Propiedad.
     * @return Nombre de la Propiedad.
     */
    public String getName() {
        return strName;
    }

    /**
     * Establece el Nombre de la Propiedad.
     * @param name Nombre de la Propiedad.
     */
    public void setName(String name) {
        this.strName = name;
    }

    /**
     * Devuelve el Mensaje de Ayuda Informativa.
     * @return Mensaje de Ayuda Informativa.
     */ 
    public String getTooltips() {
        return strTooltips;
    }

    /**
     * Establece el Mensaje de Ayuda Informativa.
     * @param tooltips Mensaje de Ayuda Informativa.
     */
    public void setTooltips(String tooltips) {
        this.strTooltips = tooltips;
    }

    /**
     * Devuelve la Colección de Parametros Set definidos en la Propiedad.
     * Nota: Por defecto esta Colección tendrá un Elemento.
     * @return Colección de Parametros definidos en la Propiedad.
     * Nota: Por defecto esta Colección tendrá un Elemento.
     */
    public ArrayList<ParametroPropiedad> getObjParametrosSet() {
        return objParametrosSet;
    }

    /**
     * Establece la Colección de Parametros Set definidos en la Propiedad.
     * Nota: Por defecto esta Colección tendrá un Elemento.
     * @param objParametros  Colección de Parametros definidos en la Propiedad.
     * Nota: Por defecto esta Colección tendrá un Elemento.
     */
    public void setObjParametrosSet(ArrayList<ParametroPropiedad> objParametros) {
        this.objParametrosSet = objParametros;
    }

    /**
     * Devuelve la Colección de Parametros Get definidos en la Propiedad.
     * Nota: Por defecto esta Colección tendrá un Elemento.
     * @return Colección de Parametros definidos en la Propiedad.
     * Nota: Por defecto esta Colección tendrá un Elemento.
     */
    public ArrayList<ParametroPropiedad> getObjParametrosGet() {
        return objParametrosGet;
    }

    /**
     * Establece la Colección de Parametros Get definidos en la Propiedad.
     * Nota: Por defecto esta Colección tendrá un Elemento.
     * @param objParametrosGet Colección de Parametros Get definidos en la Propiedad.
     * Nota: Por defecto esta Colección tendrá un Elemento.
     */
    public void setObjParametrosGet(ArrayList<ParametroPropiedad> objParametrosGet) {
        this.objParametrosGet = objParametrosGet;
    }    

    /**
     * Devuevle los Indices de Propiedades requeridas para la implementación.
     * @return Indices de Propiedades requeridas para la implementación.
     */
    public String getRequeridas() {
        return strRequeridas;
    }

    /**
     * Establece los Indices de Propiedades requeridas para la implementación.
     * @param requeridas Indices de Propiedades requeridas para la implementación.
     */
    public void setRequeridas(String requeridas) {
        this.strRequeridas = requeridas;
    }

    /**
     * Devuelve el Nombre del Método de Acceso a la <code>Propiedad</code>.
     * @return Nombre del Método de Acceso a la <code>Propiedad</code>.
     */
    public String getSet() {
        return strSet;
    }

    /**
     * Establece el Nombre del Método de Acceso a la <code>Propiedad</code>.
     * @param set Nombre del Método de Acceso a la <code>Propiedad</code>.
     */
    public void setSet(String set) {
        this.strSet = set;
    }

    /**
     * Devuelve el Nombre del Método de edición de la <code>Propiedad</code>.
     * @return Nombre del Método de edición de la <code>Propiedad</code>.
     */
    public String getGet() {
        return strGet;
    }

    /**
     * Establece el Nombre del Método de edición de la <code>Propiedad</code>.
     * @param get Nombre del Método de edición de la <code>Propiedad</code>.
     */
    public void setGet(String get) {
        this.strGet = get;
    }   

    /**
     * Devuelve el Estado que indica si la <code>Propiedad</code> ha sido aplicada al <code>Componente</code> padre.
     * @return Estado que indica si la <code>Propiedad</code> ha sido aplicada al <code>Componente</code> padre.
     */
    public boolean isAplicada() {
        return aplicada;
    }

    /**
     * Establece el Estado que indica si la <code>Propiedad</code> ha sido aplicada al <code>Componente</code> padre.
     * @param aplicada Estado que indica si la <code>Propiedad</code> ha sido aplicada al <code>Componente</code> padre.
     */
    public void setAplicada(boolean aplicada) {
        this.aplicada = aplicada;
    }

    /**
     * Devuelve el Modo de Inicialización de la <code>Propiedad</code> este modo define el proceso
     * inicial de inicialización del Valor. Los cuales pueden ser:
     * <code>INIT_NULL</code>, <code>INIT_USUARIO</code>, <code>INIT_APP</code>, <code>INIT_PROPERTIES</code>.
     * @return Modo de Inicialización de la <code>Propiedad</code> este modo define el proceso
     * inicial de inicialización del Valor. Los cuales pueden ser:
     * <code>INIT_NULL</code>, <code>INIT_USUARIO</code>, <code>INIT_APP</code>, <code>INIT_PROPERTIES</code>.
     */
    public int getInicializado() {
        return inicializado;
    }

    /**
     * Establece el Modo de Inicialización de la <code>Propiedad</code> este modo define el proceso
     * inicial de inicialización del Valor. Los cuales pueden ser:
     * <code>INIT_NULL</code>, <code>INIT_USUARIO</code>, <code>INIT_APP</code>, <code>INIT_PROPERTIES</code>.
     * @param inicializado Modo de Inicialización de la <code>Propiedad</code> este modo define el proceso
     * inicial de inicialización del Valor. Los cuales pueden ser:
     * <code>INIT_NULL</code>, <code>INIT_USUARIO</code>, <code>INIT_APP</code>, <code>INIT_PROPERTIES</code>.
     */
    public void setInicializado(int inicializado) {
        this.inicializado = inicializado;
    }

    /**
     * Devuelve el Estado que indica si se generará acceso a la <code>Propiedad</code> 
     * en el código fuente para devolver su Valor actual.     
     * @return Estado que indica que se generará acceso a la <code>Propiedad</code> 
     * en el código fuente para devolver su Valor actual.     
     */
    public boolean isViewGet() {
        return viewGet;
    }

    /**
     * Establece el Estado que indica si se generará acceso a la <code>Propiedad</code> 
     * en el código fuente para devolver su Valor actual.     
     * @param viewGet Estado que indica que se generará acceso a la <code>Propiedad</code> 
     * en el código fuente para devolver su Valor actual.     
     */
    public void setViewGet(boolean viewGet) {
        this.viewGet = viewGet;
    }

    /**
     * Devuelve el Estado que indica si se generará acceso a la <code>Propiedad</code> 
     * en el código fuente para modificar su Valor actual.     
     * @return Estado que indica que se generará acceso a la <code>Propiedad</code> 
     * en el código fuente para modificar su Valor actual.
     */
    public boolean isViewSet() {
        return viewSet;
    }

    /**
     * Establece el Estado que indica si se generará acceso a la <code>Propiedad</code> 
     * en el código fuente para modificar su Valor actual.
     * @param viewSet Estado que indica que se generará acceso a la <code>Propiedad</code> 
     * en el código fuente para modificar su Valor actual.
     */
    public void setViewSet(boolean viewSet) {
        this.viewSet = viewSet;
    }
    
    /**
     * Devuelve el Valor de la <code>Propiedad</code>. Este es el Método por defecto y se asume
     * que en la mayoria de casos la <code>Propiedad</code> solo tiene un Valor.
     * @return Valor de la <code>Propiedad</code>. Este es el Método por defecto y se asume
     * que en la mayoria de casos la <code>Propiedad</code> solo tiene un Valor.
     */
    public Object getValue(){
       try{
        return this.objParametrosSet.get(0).getStrValue();
        }catch(java.lang.IndexOutOfBoundsException ex){}
       return null;
    }    
    
    /**
     * Establece el Valor de la <code>Propiedad</code>. Este es el Método por defecto y se asume
     * que en la mayoria de casos la <code>Propiedad</code> solo tiene un Valor.
     * @param objValue Valor de la <code>Propiedad</code>. Este es el Método por defecto y se asume
     * que en la mayoria de casos la <code>Propiedad</code> solo tiene un Valor.
     */
    public void setValue(Object objValue){
       try{
        this.objParametrosSet.get(0).setStrValue(String.valueOf(objValue));
        }catch(java.lang.IndexOutOfBoundsException ex){}
       
    }
    
    
    
    /**
     * Devuelve el Valor parcial de la <code>Propiedad</code> en la Posición i.
     * Este Método se palica a caso donde la Propiedad Contiene multiples parametros.
     * @param i Posición i del Parametro.
     * @return Valor parcial de la <code>Propiedad</code> en la Posición i.
     * Este Método se palica a caso donde la Propiedad Contiene multiples parametros.
     */
    public Object getValue(int i){
       try{
        return this.objParametrosSet.get(i).getStrValue();
    }catch(java.lang.IndexOutOfBoundsException ex){}
       return null;
    }
    
    /**
     * Devuelve el Parametro por defecto de la Propiedad indicado por el modo.
     * Nota: El Parametro por defecto es el elemento en la Posición 0 de la Colección.
     * @param modo indica el modo de devolución del parametro (set - get)
     * @return Parametro por defecto de la Propiedad indicado por el modo.
     */
    public ParametroPropiedad getObjParametroDefault(int modo){
        try{
            return this.getObjParametro(0, modo);
        }catch(java.lang.NullPointerException ex){}
        return null;
    }
    
    /**
     * Devuelve el Parametro en la posición indicada por index de la Propiedad de acuerdo al modo de devolución.
     * @param index Indice en la Colección indica por el modo.
     * @param modo indica el modo de devolución del parametro (set - get)
     * @return Parametro en la posición indicada por index de la Propiedad de acuerdo al modo de devolución.
     */
    public ParametroPropiedad getObjParametro(int index, int modo){
        try{
            if(modo == Propiedad.MODO_GET){
                return this.objParametrosGet.get(index);            
            }        
            else if(modo == Propiedad.MODO_SET){
                return this.objParametrosSet.get(index);            
            }
            return this.objParametrosSet.get(index);
        }catch(java.lang.NullPointerException ex){}
        return null;
    }
    
    /**
     * Establece el Valor parcial de la <code>Propiedad</code> en la Posición i.
     * Este Método se palica a caso donde la Propiedad Contiene multiples parametros.
     * @param objValue Valor parcial de la <code>Propiedad</code> en la Posición i.
     * Este Método se palica a caso donde la Propiedad Contiene multiples parametros.
     * @param i Posición i del Parametro.
     */
    public void setValue(Object objValue, int i){
       try{
        this.objParametrosSet.get(i).setStrValue(String.valueOf(objValue));
        }catch(java.lang.IndexOutOfBoundsException ex){}
       
    }
    
    /**
     * Devuelve la Colección de Parametros de la Propiedad.
     * @return Colección de Parametros de la Propiedad.
     * @see #getObjParametrosSet() 
     */
    public Object getValues(){
        try{
            return this.getObjParametrosSet();
         }catch(java.lang.NullPointerException ex){}
        return null;
    }    
    
    /**
     * Establece la Colección de Parametros de la Propiedad.
     * @param objParametros Colección de Parametros de la Propiedad.
     * @see #setObjParametrosSet(java.util.ArrayList) 
     */
    public void setValue(ArrayList<ParametroPropiedad> objParametros){
        this.setObjParametrosSet(objParametros);
    }

    /**
     * Devuelve el Contexto de la Propiedad.
     * Nota: Solo a nivel interno.
     * @return Contexto de la Propiedad.
     */
    public int getContexto() {
        return contexto;
    }

    /**
     * Establece el Contexto de la Propiedad.
     * @param contexto Contexto de la Propiedad.
     */
    public void setContexto(int contexto) {
        this.contexto = contexto;
    }

    @Override
    public String toString() {
        return strAlias;
    }

    @Override
    public int compareTo(Object o) {
        try{
            Propiedad obj = (Propiedad) o;
            if(this.id > obj.id)
                return 1;
            else if(this.id < obj.id)
                return -1;
            else
                return 0;
        }catch(java.lang.NullPointerException ex){}
        return 0;
    }

    @Override
    public Object clone() {
        try{
        Propiedad objClon = null;
        //----------------------------------------------------------
        //Primero se Clona la Referencia Local
        //----------------------------------------------------------
        objClon = (Propiedad) super.clone();
        //----------------------------------------------------------
        //Ahora se hace la Clonación Profunda
        //----------------------------------------------------------        
        if(this.strAlias != null){
            ((Propiedad)objClon).strAlias = new String(strAlias.toCharArray());
        }        
        if(this.strGet != null){
            ((Propiedad)objClon).strGet = new String(strRequeridas.toCharArray());
        }
        if(this.strName != null){
            ((Propiedad)objClon).strName = new String(strName.toCharArray());
        }
        if(this.objParametrosGet != null){
            ((Propiedad)objClon).objParametrosGet = (ArrayList<ParametroPropiedad>) objParametrosGet.clone();
        }
        if(this.objParametrosSet != null){
            ((Propiedad)objClon).objParametrosSet = (ArrayList<ParametroPropiedad>) objParametrosSet.clone();
        }
        if(this.strRequeridas != null){
            ((Propiedad)objClon).strRequeridas = new String(strRequeridas.toCharArray());
        }
        if(this.strSet != null){
            ((Propiedad)objClon).strSet = new String(strSet.toCharArray());
        }
        if(this.strTooltips != null){
            ((Propiedad)objClon).strTooltips = new String(strTooltips.toCharArray());
        }        
        return objClon;
    }catch(java.lang.NullPointerException ex){}
        return null;
    }
    
    
}
